using System;
using System.Collections.Generic;
using MLSharp;
using MLSharp.Classification;
using MLSharp.Evaluation;
using MLSharp.Filters;

namespace MLSharp.ConsoleRunner
{
	/// <summary>
	/// A harness that trains each classifier on the entire data set,
	/// then classifies the entire data set.  
	/// </summary>
	public class SimpleClassificationHarness : IHarness
	{
		#region Logger

		/// <summary>
		/// The logger for the type.
		/// </summary>
		private static readonly log4net.ILog mLogger =
			log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

		#endregion

		#region Private Fields

		/// <summary>
		/// The classifier factories to use for processing data sets.
		/// </summary>
		private readonly IClassifierFactory[] mClassifierFactories;

		#endregion

		#region Public Properties

		/// <summary>
		/// Flag that indicates whether or not the harness should attempt
		/// to parallelize classifier execution.
		/// </summary>
		public bool RunInParallel { get; set; }

		/// <summary>
		/// The result writers to write classification results to.
		/// </summary>
		public IList<IResultWriter> ResultWriters { get; private set; }

		/// <summary>
		/// The filters to apply to the dataset.
		/// </summary>
		public IList<IDataSetFilter> Filters { get; private set; }

		#endregion

		#region Public Constructors

		/// <summary>
		/// Creates the harness with the specified factories.
		/// </summary>
		/// <param name="classifierFactories"></param>
		public SimpleClassificationHarness(IClassifierFactory[] classifierFactories)
		{
			mClassifierFactories = classifierFactories;

			ResultWriters = new List<IResultWriter>();
		}

		#endregion

		#region Public Methods

		/// <summary>
		/// Runs the harness.
		/// </summary>
		/// <param name="dataSet">The data set to use.</param>
		public void Run(IDataSet dataSet)
		{
			//TODO: Rewrite this to handle multiple classifiers.  Maybe we can only
			//		 handle one at a time?
			throw new NotImplementedException();
			////Tell the result writer about the classifiers we'll be sending it results for.
			//foreach (IResultWriter writer in ResultWriters)
			//{
			//    //Add all the classifiers
			//    foreach (IClassifierFactory factory in mClassifierFactories)
			//    {
			//        writer.AddClassifier(factory.GetType().Name);
			//    }
			//}

			//ClassificationResult[][] results = new ClassificationResult[mClassifierFactories.Length][];

			//for (int i = 0; i < mClassifierFactories.Length; i++)
			//{
			//    //Train The classifier...
			//    mLogger.DebugFormat("Training {0}...", mClassifierFactories[i].GetType().Name);

			//    IClassifier classifier = mClassifierFactories[i].BuildClassifier(dataSet);

			//    mLogger.Debug("Classifying...");

			//    results[i] = classifier.Classify(dataSet);
			//}
		}

		#endregion
	}
}
